package model;

import java.io.File;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.Semaphore;

import util.DangerousException;
import util.Message;
import util.MsgType;

public class Foot implements Runnable {

	private int id;
	private File dir;
	private State state;
	private LinkedBlockingQueue<Message> pipe;
	private Semaphore step;
	private CyclicBarrier barrier;

	public Foot() {
	}
	
	public Foot(int id, String path, State state, LinkedBlockingQueue<Message> pipe, Semaphore step, CyclicBarrier barrier) {
		this.id = id;
		this.dir = new File(path);
		this.state = state;
		this.pipe = pipe;
		this.step = step;
		this.barrier = barrier;
	}
	
	public synchronized void waitForStep() throws InterruptedException {
		while (!state.activeness(id)) {
			wait();
		}
	}


	@Override
	public void run() {
		state.feetReady.countDown();
		try {
			state.headReady.await();
			
			while(true) {
				//waiting for releasing semaphore by Head
				step.acquire();
				try {
					for(String file : dir.list()) {
						if(file.equals("danger.dat")) {
							throw new DangerousException();
						}
					}
	
					
					// step could be done
					state.step();
					pipe.put(new Message(MsgType.info, "ok"));
					
				} catch(DangerousException ex) {
					pipe.put(new Message(MsgType.info, "fail"));
				}

				step.release();
				
				barrier.await();	
			}
			
		} catch(InterruptedException e) {
			//System.out.println("Interrupted exception occured. Program interrupted.");
			pipe.add(new Message(MsgType.exception, e));
		} catch (BrokenBarrierException e) {
			//System.out.println("BrokenBarrier exception occured. Program interrupted.");
			pipe.add(new Message(MsgType.exception, e));
		}
	}

}
